package com.house.Interceptor;

import com.alibaba.fastjson.JSON;
import com.house.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;


/**
 * 用户登录拦截器
 */
@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {


    // 定义路径匹配器--用于下方的checkPath()方法匹配请求路径和放行路径是否存在匹配（固定写法）。
    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();

    // 定义直接放行的资源请求(根据自己实际情况定义放行的资源)
    public static final String[] URLS = new String[]{
            "/",
            "/preview/**",
            "/dict/**",
            "/**/public/**",
            //登录页面的请求
            "/login",
            "/register",
            //下方访问静态页面可以放行，但是在静态页面发送的分页数据请求是会过滤的
            //例如:当一访问manege页面就会请求获取分页数据，就会向/users发送
            //请求，然会就会进行登录检查
//            "/html/**",
//            "/jsp/**",
//            "/js/**",
            "/static/**",
            "/error",
            "/favicon.ico"
    };


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 获取当前访问的URL，用以判断是否直接放行
        String requestURI = request.getRequestURI();
        log.info("当前的URI是：{}", requestURI);



        // 检查当前请求是否需要进行过滤（true代表匹配成功，直接放行）
        if(checkPath(URLS, requestURI)) {
            // 如果匹配成功，则放行
            log.info("资源直接放行...");
            return true;
        }

        log.info("未放行： {}", requestURI);

        // 捕获到需要过滤的请求，检查是否有登录后赋予的session（检查是否已登录）
        if(request.getSession().getAttribute("user") == null) {
            if(isAjax(request)) {
                String resStr = JSON.toJSONString(Result.error("未登录，请先登录！"));
                response.getOutputStream().write(resStr.getBytes(StandardCharsets.UTF_8));
            } else {
                response.sendRedirect(request.getContextPath() + "/login");
            }

            return false;
        }

        return true;
    }


    /**
     * 路径匹配方法
     * @param urls 需要放行的请求路径数组
     * @param targetUrl 需要检查的请求路径
     * @return 返回是否匹配成功
     */
    private Boolean checkPath(String[] urls,String targetUrl){
        for (String url : urls) {
            if (PATH_MATCHER.match(url, targetUrl)){
                return true;
            }
        }
        return false;
    }


    /**
     * 判断是否ajax请求
     * @param request
     * @return
     */
    private Boolean isAjax(HttpServletRequest request) {
        // 获取头部信息 pc
        String xRequestedWith = request.getHeader("X-Requested-With");
        if(xRequestedWith!= null && xRequestedWith.contains("XMLHttpRequest")){
            return true;
        } else {
            return false;
        }


//        // 获取头部信息 手机
//        String accept = request.getHeader("accept");
//        if(accept!= null && accept.indexOf("application/json") != -1){
//            return true;
//        }else{
//            return false;
//        }
    }
}
